package com.weaver.seconddev.api.tl.gr_nbs_cancel_api;

/**
 * E9原始类路径:com.api.tl.gr_nbs_cancel_api.GrCacelPoAction
 * JAVA替换说明文档:https://ncnb71xwgeda.feishu.cn/wiki/JLsjwxK8xiHuPIkdu0Dc27Rlnaf?from=from_copylink
 */
import cn.hutool.core.collection.CollectionUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.parser.Feature;
import com.weaver.seconddev.api.tl.gr_api.GrService;
import lombok.Getter;
import lombok.Setter;
import org.apache.commons.lang3.StringUtils;
import java.text.SimpleDateFormat;
import java.util.*;
import com.weaver.common.i18n.tool.util.I18nContextUtil;
import com.weaver.verupgrade.conn.CONN_TYPE;
import java.lang.*;

import org.slf4j.LoggerFactory;
import com.weaver.verupgrade.workflow.request.RequestManager;
import com.weaver.esb.api.rpc.EsbServerlessRpcRemoteInterface;
import com.weaver.common.base.entity.result.WeaResult;
import org.springframework.beans.factory.annotation.Autowired;
import com.weaver.verupgrade.soa.workflow.request.RequestInfo;
import java.util.Map;
import java.util.HashMap;
import com.weaver.verupgrade.conn.RecordSet;
import com.weaver.verupgrade.interfaces.workflow.action.Action;

import javax.annotation.Resource;

/**
 * 生成GR号码接口，节点后事件执行
 */
@org.springframework.stereotype.Service("tl_gr_nbs_cancel_api_GrCacelPoAction")
public class GrCacelPoAction implements Action, EsbServerlessRpcRemoteInterface {

    // 对应E9的请求信息对象
    @Autowired
    private RequestInfo requestInfoTemp;

    public static final org.slf4j.Logger logger_1bca93fc = LoggerFactory.getLogger(GrCacelPoAction.class);


    @Resource(name = "tl_gr_api_GrService")
    private GrService grService;

    @Getter
    @Setter
    public String // 流程主表名
            workflowTableName;

    @Getter
    @Setter
    public String // 流程明细表名
            workflowDetailTableName;

    @Override
    public WeaResult<Map<String, Object>> execute(Map<String, Object> requestInfoMap) {
        Map<String, Object> weaverResultMap = new HashMap<>();
        Long requestIdTemp = Long.parseLong(String.valueOf(requestInfoMap.getOrDefault("requestid", -1)));
        Long userIdTemp = Long.parseLong(String.valueOf(requestInfoMap.getOrDefault("userid", -1)));
        workflowTableName = String.valueOf(requestInfoMap.getOrDefault("workflowTableName", ""));
        workflowDetailTableName = String.valueOf(requestInfoMap.getOrDefault("workflowDetailTableName", ""));
        RequestInfo requestInfo = requestInfoTemp.getRequestInfo(requestIdTemp, userIdTemp);
        String pushApprovedResult = SUCCESS;
        /* 获取requestId
 TODO 返回值:requestId 存在类型转换风险 e9类型:java.lang.String e9真实类型: int  e10类型:java.lang.String e10真实类型: long */
        String requestId = requestInfo.getRequestid();
        RecordSet recordSet = I18nContextUtil.getBean(RecordSet.class);
        logger_1bca93fc.info(String.valueOf("RequestId:" + requestId + "======Into nbs workflow GrPoAction======"));
        try {
            // 主表查询
            //String querySQL = "select\n" + "  m.id as id,\n" + "  m.request_number as headerText,\n" + "  m.po as poNumber,\n" + "  m.kbs_operator as createdBy,\n" + "  m.posting_date as postingDate,\n" + " '101' as movementType,\n" + "  'B' as moveIndicator,\n" + "  '' as storageLocation,\n" + "  m.requestId as ref\n" + "from\n" + "  " + workflowTableName + " m\n" + "where\n" + "  requestId = '" + requestId + "'";
            String querySQL = "SELECT m.id as id, m.request_number as headerText,  m.po as poNumber,  m.kbs_operator as createdBy, m.posting_date as postingDate, '101' as movementType, 'B' as moveIndicator, '' as storageLocation, m.requestId as ref " +
                    "FROM (\n" +
                    "\tSELECT b.*, a.requestid\n" +
                    "\tFROM e10_core_business.wfc_form_data a, e10_core_business."+workflowTableName+" b\n" +
                    "\tWHERE a.dataid = b.form_data_id\n" +
                    "\t\tAND a.delete_type = 0\n" +
                    "\t\tAND a.tenant_key = 'tl2k2r96ty'\n" +
                    ") m\n" +
                    "WHERE m.requestid = '"+ requestId +"'" +
                    "\tAND m.delete_type = 0\n" +
                    "\tAND m.tenant_key = 'tl2k2r96ty'";
            logger_1bca93fc.info(String.valueOf("querySQL=>" + querySQL));
            String poolname_w2 = CONN_TYPE.workflow.getType();
            // TODO E10执行sql方法第二参数必须指定源，默认使用流程源，单体客户无需修改，微服务/组合客户需根据查询表所属服务切换源，或使用外部数据源
            recordSet.executeQuery(querySQL, poolname_w2);
            Map<String, Object> headerMap = new LinkedHashMap<>();
            // 明细表关联ID
            String mainId = "";
            // 主表PoNumber
            String poNumber = "";
            if (recordSet.next()) {
                mainId = recordSet.getString("id");
                String headerText = recordSet.getString("headerText");
                String ref = recordSet.getString("ref");
                String postingDate = recordSet.getString("postingDate");
                poNumber = recordSet.getString("poNumber");
                headerMap.put("postingDate", postingDate);
                headerMap.put("ref", ref);
                headerMap.put("createdBy", "SYS_AWS_INT");
                headerMap.put("headerText", headerText);
            }
            // 明细表查询
            querySQL = "select  \n" +
                    "select d.item as poItem,  d.bcgr_qty as cancelQuantity,d.received_quantity as residueQuantity,d.mat_doc as matDoc,d.doc_year as docYear,d.matdoc_itm as matDocItm,d.material as material , d.unit as unit, '101' as movementType, 'B' as moveIndicator,'' as storageLocation  from  "+ workflowDetailTableName + " FROM e10_core_business."+workflowDetailTableName+" d\n" +
                    "WHERE d.form_data_id = "+mainId+"\n" +
                    "\tAND d.ok = 1\n" +
                    "\tAND d.delete_type = 0\n" +
                    "\tAND d.tenant_key = 'tl2k2r96ty'";;
            logger_1bca93fc.info(String.valueOf("querySQL=>" + querySQL));
            String poolname_hw = CONN_TYPE.workflow.getType();
            // TODO E10执行sql方法第二参数必须指定源，默认使用流程源，单体客户无需修改，微服务/组合客户需根据查询表所属服务切换源，或使用外部数据源
            recordSet.executeQuery(querySQL, poolname_hw);
            List<Map<String, Object>> cancelMapList = new ArrayList<>();
            List<Map<String, Object>> itemList = new LinkedList<>();
            while (recordSet.next()) {
                String material = recordSet.getString("material");
                String storageLocation = recordSet.getString("storageLocation");
                String movementType = recordSet.getString("movementType");
                // 已GR数量
                String residueQuantity = recordSet.getString("residueQuantity");
                // 需要取消的GR数量
                String cancelQuantity = recordSet.getString("cancelQuantity");
                // 剩余-取消 = 需要创建的GR数量
                Double quantity = Double.parseDouble(residueQuantity) - Double.parseDouble(cancelQuantity);
                String poItem = recordSet.getString("poItem");
                String moveIndicator = recordSet.getString("moveIndicator");
                String unit = recordSet.getString("unit");
                if (quantity > 0d) {
                    // 需要创建的GR数据
                    Map<String, Object> tempTemp = new LinkedHashMap<>();
                    tempTemp.put("material", material);
                    tempTemp.put("storageLocation", storageLocation);
                    tempTemp.put("movementType", movementType);
                    tempTemp.put("quantity", String.format("%.2f", quantity));
                    tempTemp.put("unit", unit);
                    tempTemp.put("poNumber", poNumber);
                    tempTemp.put("poItem", poItem);
                    tempTemp.put("moveIndicator", moveIndicator);
                    itemList.add(tempTemp);
                }
                // 需要取消的GR数据
                Map<String, Object> cancelMap = new HashMap<>();
                // GR号
                String matDoc = recordSet.getString("matDoc");
                // GR Year
                String docYear = recordSet.getString("docYear");
                // GR取消的ITEM值
                String matDocItm = recordSet.getString("matDocItm");
                cancelMap.put("matDocument", matDoc);
                cancelMap.put("matDocumentYear", docYear);
                cancelMap.put("postingDate", new SimpleDateFormat("yyyy-MM-dd").format(new Date()));
                cancelMap.put("items", new String[] { matDocItm });
                cancelMapList.add(cancelMap);
            }
            // 取消GR号码
            for (Map<String, Object> cancelMap : cancelMapList) {
                JSONObject jsonObject = (JSONObject) JSONObject.toJSON(cancelMap);
                JSONObject retObject = grService.reverseGR(jsonObject);
                if (retObject.getString("matDoc") == null) {
                    // 为空代表 取消失败
                    throw new RuntimeException("param object = " + jsonObject.toJSONString() + ",return object = " + retObject.toJSONString() + " ");
                }
            }
            // 创建GR
            if (CollectionUtil.isNotEmpty(itemList)) {
                Map<String, Object> dataMap = new LinkedHashMap<>();
                dataMap.put("header", headerMap);
                dataMap.put("items", itemList);
                // 调用创建GR号码
                JSONObject dataObject = JSONObject.parseObject(JSON.toJSONString(dataMap), Feature.OrderedField);
                JSONObject retJsonObject = grService.postGR(dataObject);
                // 返回GR号码
                String matDoc = retJsonObject.getString("matDoc");
                // 年份
                String matDocYear = retJsonObject.getString("matDocYear");
                if (StringUtils.isBlank(matDoc)) {
                    logger_1bca93fc.info("post sap GR failure retObject =>" + retJsonObject);
                    throw new RuntimeException("param object = " + JSON.toJSONString(dataMap) + ",return object = " + retJsonObject.toJSONString() + " ");
                }
            }
        } catch (Exception exception) {
            pushApprovedResult = FAILURE_AND_CONTINUE;
            logger_1bca93fc.info(String.valueOf(exception.getMessage()));
            //String updateSQL = "update " + workflowTableName + " set error_msg = ? where requestId = ?";
            String updateSQL = "UPDATE (\n" +
                    "\tSELECT b.*, a.requestid\n" +
                    "\tFROM e10_core_business.wfc_form_data a, e10_core_business."+workflowTableName+" b\n" +
                    "\tWHERE a.dataid = b.form_data_id\n" +
                    "\t\tAND a.delete_type = 0\n" +
                    "\t\tAND a.tenant_key = 'tl2k2r96ty'\n" +
                    ") "+workflowTableName+"\n" +
                    "SET error_msg = ? \n" +
                    "WHERE form_data_id IN (\n" +
                    "\t\tSELECT dataid AS dataid\n" +
                    "\t\tFROM e10_core_business.wfc_form_data\n" +
                    "\t\tWHERE "+workflowTableName+".requestid = ? \n" +
                    "\t\t\tAND wfc_form_data.delete_type = 0\n" +
                    "\t\t\tAND wfc_form_data.tenant_key = 'tl2k2r96ty'\n" +
                    "\t)\n" +
                    "AND "+workflowTableName+".delete_type = 0\n" +
                    "AND "+workflowTableName+".tenant_key = 'tl2k2r96ty'";;
            logger_1bca93fc.info(String.valueOf("update errorMsg SQL = " + updateSQL));
            String poolname = CONN_TYPE.workflow.getType();
            // TODO E10执行sql方法第二参数必须指定源，默认使用流程源，单体客户无需修改，微服务/组合客户需根据查询表所属服务切换源，或使用外部数据源
            recordSet.executeUpdate(updateSQL, poolname, exception.getMessage(), requestId);
        }
        logger_1bca93fc.info(String.valueOf("RequestId:" + requestId + "======Out GrPoAction Action======ReturnResult:" + pushApprovedResult));
        return WeaResult.success(getResultMapForAction(weaverResultMap, "result", pushApprovedResult, requestInfo.getRequestManager()));
    }

    Map<String, Object> getResultMapForAction(Map<String, Object> map, String key, Object value, RequestManager requestManager) {
        if (key != null && !key.isEmpty()) {
            map.put(key, value);
        }
        String msgContent = requestManager.getMessagecontent();
        if (msgContent != null && !msgContent.isEmpty()) {
            map.put("msgContent", msgContent);
        }
        String msgId = requestManager.getMessageid();
        if (msgId != null && !msgId.isEmpty()) {
            map.put("msgId", msgId);
        }
        return map;
    }
}
